import time
import os

from PySide6 import QtGui, QtCore
from .ui_main import *



# FUNCTIONS
class MainFunctions:
    def __init__(self):
        super().__init__()
        # SETUP MAIN WINDOw
        # Load widgets from "gui\uis\main_window\ui_main.py"
        # ///////////////////////////////////////////////////////////////
        self.ui = UI_MainWindow()
        self.ui.setup_ui(self)

    # SET MAIN WINDOW PAGES
    # ///////////////////////////////////////////////////////////////
    def set_page(self, page):
        self.ui.load_pages.pages.setCurrentWidget(page)

    # SET LEFT COLUMN PAGES
    # ///////////////////////////////////////////////////////////////
    def set_left_column_menu(
            self,
            menu,
            title,
            icon_path
    ):
        self.ui.left_column.menus.menus.setCurrentWidget(menu)
        self.ui.left_column.title_label.setText(title)
        self.ui.left_column.icon.set_icon(icon_path)

    # RETURN IF LEFT COLUMN IS VISIBLE
    # ///////////////////////////////////////////////////////////////
    def left_column_is_visible(self):
        width = self.ui.left_column_frame.width()
        if width == 0:
            return False
        else:
            return True

    # RETURN IF RIGHT COLUMN IS VISIBLE
    # ///////////////////////////////////////////////////////////////
    def right_column_is_visible(self):
        width = self.ui.right_column_frame.width()
        if width == 0:
            return False
        else:
            return True

    # SET RIGHT COLUMN PAGES
    # ///////////////////////////////////////////////////////////////
    def set_right_column_menu(self, menu):
        self.ui.right_column.menus.setCurrentWidget(menu)

    # GET TITLE BUTTON BY OBJECT NAME
    # ///////////////////////////////////////////////////////////////
    def get_title_bar_btn(self, object_name):
        return self.ui.title_bar_frame.findChild(QPushButton, object_name)

    # GET TITLE BUTTON BY OBJECT NAME
    # ///////////////////////////////////////////////////////////////
    def get_left_menu_btn(self, object_name):
        return self.ui.left_menu.findChild(QPushButton, object_name)

    # LEDT AND RIGHT COLUMNS / SHOW / HIDE
    # ///////////////////////////////////////////////////////////////
    def toggle_left_column(self):
        # GET ACTUAL CLUMNS SIZE
        width = self.ui.left_column_frame.width()
        right_column_width = self.ui.right_column_frame.width()
        MainFunctions.start_box_animation(self, width, right_column_width, "left")

    def toggle_right_column(self):
        # GET ACTUAL CLUMNS SIZE
        left_column_width = self.ui.left_column_frame.width()
        width = self.ui.right_column_frame.width()
        MainFunctions.start_box_animation(self, left_column_width, width, "right")

    def start_box_animation(self, left_box_width, right_box_width, direction):
        right_width = 0
        left_width = 0
        time_animation = self.ui.settings["time_animation"]
        minimum_left = self.ui.settings["left_column_size"]["minimum"]
        maximum_left = self.ui.settings["left_column_size"]["maximum"]
        minimum_right = self.ui.settings["right_column_size"]["minimum"]
        maximum_right = self.ui.settings["right_column_size"]["maximum"]

        # Check Left Values        
        if left_box_width <= minimum_left and direction == "left":
            left_width = maximum_left
        else:
            left_width = minimum_left

        # Check Right values        
        if right_box_width <= minimum_right and direction == "right":
            right_width = maximum_right
        else:
            right_width = minimum_right

            # ANIMATION LEFT BOX
        self.left_box = QPropertyAnimation(self.ui.left_column_frame, b"minimumWidth")
        self.left_box.setDuration(time_animation)
        self.left_box.setStartValue(left_box_width)
        self.left_box.setEndValue(left_width)
        self.left_box.setEasingCurve(QEasingCurve.InOutQuart)

        # ANIMATION RIGHT BOX        
        self.right_box = QPropertyAnimation(self.ui.right_column_frame, b"minimumWidth")
        self.right_box.setDuration(time_animation)
        self.right_box.setStartValue(right_box_width)
        self.right_box.setEndValue(right_width)
        self.right_box.setEasingCurve(QEasingCurve.InOutQuart)

        # GROUP ANIMATION
        self.group = QParallelAnimationGroup()
        self.group.stop()
        self.group.addAnimation(self.left_box)
        self.group.addAnimation(self.right_box)
        self.group.start()

    def set_select_path(self, obj):
        folder_path = QFileDialog.getExistingDirectory(self, "选择文件夹")
        obj.setText(folder_path)

    def set_select_file(self, obj):
        file_path, file_name = QFileDialog.getOpenFileName(self, "选择文件")
        obj.setText(file_path)

    def open_directory(self):
        if os.path.isdir(self.app1_line_edit.text()):
            QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(self.app1_line_edit.text()))

    def set_text(self, mode, data):
        current_time = time.time()
        seconds = time.strftime("%H:%M:%S", time.localtime(current_time))
        if mode == " [Info]":
            temp_data = seconds + mode + data
        if mode == " [Attention]":
            color = self.ColorPalette.green
            temp_data = f"<font color=\"{color}\">" + seconds + mode + data + "</font> "
        if mode == " [Warning]":
            color = self.ColorPalette.yellow
            temp_data = f"<font color=\"{color}\">" + seconds + mode + data + "</font> "
        if mode == " [Error]":
            color = self.ColorPalette.red
            temp_data = f"<font color=\"{color}\">" + seconds + mode + data + "</font> "

        self.app1_log_output_textbr.append(temp_data)
        self.app1_log_output_textbr.moveCursor(QTextCursor.End)

    def gen_report(self):
        path = self.app1_line_edit.text()
        self.app1_log_output_textbr.setText("")
        self.Tread_app1 = xlsx_cases(app_lang=self.app_lang, folder_path=path,
                                     form_width=float(self.app1_gen_doc_parm_1.text()[:-2]))
        self.Tread_app1.info.connect(lambda x: MainFunctions.set_text(self, " [Info]", x))
        self.Tread_app1.warning.connect(lambda x: MainFunctions.set_text(self, " [Warning]", x))
        self.Tread_app1.error.connect(lambda x: MainFunctions.set_text(self, " [Error]", x))
        self.Tread_app1.special.connect(lambda x: MainFunctions.set_text(self, " [Attention]", x))
        self.Tread_app1.started.connect(None)
        self.Tread_app1.finished.connect(None)
        self.Tread_app1.finished.connect(lambda: self.Tread_app1.deleteLater())
        self.Tread_app1.start()

    def dp832_start(self):
        if self.app3_dp832_line_edit.text():
            dev_name = self.app3_dp832_line_edit.text()
        elif self.spmk_dp832_line_edit.text():
            dev_name = self.spmk_dp832_line_edit.text()
        if self.Tread_app3 is None:
            self.Tread_app3 = DP832(dev_name)
            self.Tread_app3.link_ok.connect(lambda x: MainFunctions.dep832_status(self, x))
            self.Tread_app3.finished.connect(lambda: print("线程结束"))
            self.Tread_app3.finished.connect(lambda: self.Tread_app3.deleteLater())
            self.Tread_app3.start()
        else:
            self.Tread_app3.resume_thread(dev_name)

    def dep832_status(self, flag):
        if flag:
            self.app3_connet_dp832_btn.setIcon(self.app3_connet_dp832_btn_icon_ok)
            self.app3_connet_dp832_btn.setText(self.app_lang["DP832_connect_dev_btn_text_ok"])
            self.spmk_connet_dp832_btn.setIcon(self.app3_connet_dp832_btn_icon_ok)
            self.spmk_connet_dp832_btn.setText(self.app_lang["DP832_connect_dev_btn_text_ok"])
            self.app3_dp832_ch1_V_line_edit.setEnabled(True)
            self.app3_dp832_ch1_I_line_edit.setEnabled(True)
            self.app3_dp832_ch1_open_btn.setEnabled(True)
            self.app3_dp832_ch1_close_btn.setEnabled(True)

            self.app3_dp832_ch2_V_line_edit.setEnabled(True)
            self.app3_dp832_ch2_I_line_edit.setEnabled(True)
            self.app3_dp832_ch2_open_btn.setEnabled(True)
            self.app3_dp832_ch2_close_btn.setEnabled(True)

            self.app3_dp832_ch3_V_line_edit.setEnabled(True)
            self.app3_dp832_ch3_I_line_edit.setEnabled(True)
            self.app3_dp832_ch3_open_btn.setEnabled(True)
            self.app3_dp832_ch3_close_btn.setEnabled(True)
        else:
            self.app3_connet_dp832_btn.setIcon(self.app3_connet_dp832_btn_icon_no)
            self.app3_connet_dp832_btn.setText(self.app_lang["DP832_connect_dev_btn_text_no"])
            self.spmk_connet_dp832_btn.setIcon(self.app3_connet_dp832_btn_icon_no)
            self.spmk_connet_dp832_btn.setText(self.app_lang["DP832_connect_dev_btn_text_no"])

    def dp832_ch_open(self, ch):
        if ch == 1:
            cmd_list = [f":INST CH{ch}",
                        f":CURR {self.app3_dp832_ch1_I_line_edit.text()}",
                        f":VOLT {self.app3_dp832_ch1_V_line_edit.text()}",
                        f":OUTP CH{ch},ON"]
        if ch == 2:
            cmd_list = [f":INST CH{ch}",
                        f":CURR {self.app3_dp832_ch2_I_line_edit.text()}",
                        f":VOLT {self.app3_dp832_ch2_V_line_edit.text()}",
                        f":OUTP CH{ch},ON"]
        if ch == 3:
            cmd_list = [f":INST CH{ch}",
                        f":CURR {self.app3_dp832_ch3_I_line_edit.text()}",
                        f":VOLT {self.app3_dp832_ch3_V_line_edit.text()}",
                        f":OUTP CH{ch},ON"]
        self.Tread_app3.write_cmd(cmd_list)

    def spmk_dp832_set_ch(self, ch, curr, volt):
        cmd_list = [f":INST CH{ch}",
                    f":CURR {curr}",
                    f":VOLT {volt}",
                    f":OUTP CH{ch},ON"]
        self.Tread_app3.write_cmd(cmd_list)

    def dp832_ch_close(self, ch):
        cmd_list = [f":OUTP CH{ch},OFF"]
        self.Tread_app3.write_cmd(cmd_list)

    def COM__f5(self):
        self.COM_select_Combox.clear()
        import serial.tools.list_ports
        ports = list(serial.tools.list_ports.comports())
        for p in ports:
            self.COM_select_Combox.addItem(f"{p}")

    def SPMK_start(self):
        com_name = self.COM_select_Combox.currentText().split(" ")[0]
        if self.Tread_SPMK is None:
            self.Tread_SPMK = SPMK51XT(com_name)
            print(com_name)
            self.Tread_SPMK.build.connect(lambda x: MainFunctions.SPMK_status(self, x))
            self.Tread_SPMK.set_RIGOL.connect(lambda x, y, z: MainFunctions.spmk_dp832_set_ch(self, x, y, z))
            self.Tread_SPMK.finished.connect(lambda: print("线程结束"))
            self.Tread_SPMK.finished.connect(lambda: self.Tread_SPMK.deleteLater())
            self.Tread_SPMK.start()
        else:
            ll = None
            if self.Tread_SPMK.com_parm.port != com_name:
                self.Tread_SPMK.com_parm.port = com_name
                self.Tread_SPMK.resume_thread()
            if self.SPMK_lineEdit.text():
                temp = self.SPMK_lineEdit.text().split(" ")
                ll = [i for i in temp]

            self.Tread_SPMK.resume_thread(ll, self.Net_adpter_select_Combox.currentText().split(":")[0])

    def SPMK_status(self, flag):
        if flag:
            self.SPMK_connect_btn.setIcon(self.SPMK_connect_btn_btn_icon_ok)
            self.SPMK_connect_btn.setText(self.app_lang["DP832_connect_dev_btn_text_ok"])
        else:
            self.SPMK_connect_btn.setIcon(self.SPMK_connect_btn_btn_icon_no)
            self.SPMK_connect_btn.setText(self.app_lang["DP832_connect_dev_btn_text_no"])

    def config_combox_update(self):
        self.IO_config_Combox.clear()
        for i in self.io_list[f"{self.IO_select_Combox.currentText()[:4]}"].keys():
            self.IO_config_Combox.addItem(f"{i}")

    def IOConfig_run(self):
        plc_ofd = self.app2_select_plc_ofd_line_edit.text()
        io_ofd = self.app2_select_io_ofd_line_edit.text()
        pic_out = self.app2_select_savepic_folder_line_edit.text()
        self.Tread_app2 = IOConfig(plc_ofd, io_ofd, pic_out)
        # self.Tread_app2.info.connect(lambda x: MainFunctions.set_text(self, " [Info]", x))
        # self.Tread_app2.warning.connect(lambda x: MainFunctions.set_text(self, " [Warning]", x))
        # self.Tread_app2.error.connect(lambda x: MainFunctions.set_text(self, " [Error]", x))
        # self.Tread_app2.special.connect(lambda x: MainFunctions.set_text(self, " [Attention]", x))
        self.Tread_app2.status.connect(lambda x: MainFunctions.IOConfig_status(self, x))
        self.Tread_app2.started.connect(lambda: None)
        self.Tread_app2.finished.connect(lambda: None)
        self.Tread_app2.finished.connect(lambda: self.Tread_app2.deleteLater())
        self.Tread_app2.start()

    def IOConfig_status(self, flag):
        if flag:
            self.app2_run_btn.setIcon(self.app2_run_btn_icon_on)
            self.app2_run_btn.setText(self.app_lang["IOConfig_run_btn_text_on"])
        else:
            self.app2_run_btn.setIcon(self.app2_run_btn_icon_off)
            self.app2_run_btn.setText(self.app_lang["IOConfig_run_btn_text_off"])

    def scan_io(self):
        if self.Net_adpter_select_Combox.currentText() != self.app_lang["page10_net_adapter_select_combox"]:
            self.adapter_name = self.Net_adpter_select_Combox.currentText().split(":")[1]
        else:
            self.adapter_name = "Realtek PCIe GbE Family Controller"
        devs = io_scan.scan_adpter(self)
        items = []
        count = 1

        for key, value in devs.items():
            ip = key[8:-1]
            slot = 0
            dad = TreeWidgetItem(count, 0, key,
                                 icon=QIcon(Functions.set_svg_icon("icon_input_f.svg")),
                                 extend={'id': key[:7], 'ip': ip, 'slot': slot})
            items.append(dad)
            dad_lv = count
            count += 1
            slot += 1
            for k, v in value.items():
                son = TreeWidgetItem(count, dad_lv, v,
                                     icon=QIcon(Functions.set_svg_icon("icon_input_f.svg")),
                                     extend={'id': v, 'ip': ip, 'slot': slot})
                slot += 1
                items.append(son)
                count += 1
        treeData = ElTreeData(items=items)
        self.dev_tree.set_items(True, treeData=treeData)
        # self.dev_tree.show()

    def fresh_adapter(self):
        self.Net_adpter_select_Combox.clear()
        for i in get_net_adapter():
            self.Net_adpter_select_Combox.addItem(f"{i}")


class JINYEE_FUNCTIONS:

    def JINYEE_INIT(self):
        id1, id2 = self.USB_select_Combox.currentText().split(" - ")[0:2]
        if self.Tread_JINYEE is None:
            self.Tread_JINYEE = JINYEE951(int(id1), int(id2))
            self.Tread_JINYEE.build.connect(lambda x: JINYEE_FUNCTIONS.JINYEE_build(self, x))
            self.Tread_JINYEE.info.connect(lambda x: JINYEE_FUNCTIONS.JINYEE_info(self, x))
            self.Tread_JINYEE.warn.connect(lambda x: JINYEE_FUNCTIONS.JINYEE_warn(self, x))
            self.Tread_JINYEE.error.connect(lambda x: JINYEE_FUNCTIONS.JINYEE_error(self, x))
            self.Tread_JINYEE.finished.connect(lambda: print("线程结束"))
            self.Tread_JINYEE.finished.connect(lambda: self.Tread_JINYEE.deleteLater())
            self.Tread_JINYEE.start()
        else:
            JINYEE_FUNCTIONS.JINYEE_Update(self)

    def JINYEE_START(self):
        if self.Tread_JINYEE.is_paused:
            if self.JINYEE_lineEdit.text():
                temp = self.JINYEE_lineEdit.text().split(" ")
            self.Tread_JINYEE.Update_thread([i for i in temp])
        else:
            JINYEE_FUNCTIONS.JINYEE_STOP(self)

    def JINYEE_Update(self):
        id1, id2 = self.USB_select_Combox.currentText().split(" - ")[0:2]
        self.Tread_JINYEE.vendor_id, self.Tread_JINYEE.product_id = int(id1), int(id2)
        self.Tread_JINYEE.Communications_status = bool(0)
        self.Tread_JINYEE.is_paused = bool(1)

    def JINYEE_STOP(self):
        self.Tread_JINYEE.is_paused = bool(1)

    def JINYEE_build(self, flag):
        if flag:
            self.JINYEE_connect_btn.setIcon(self.JINYEE_connect_btn_btn_icon_ok)
            self.JINYEE_connect_btn.setText(self.app_lang["DP832_connect_dev_btn_text_ok"])
        else:
            self.JINYEE_connect_btn.setIcon(self.JINYEE_connect_btn_btn_icon_no)
            self.JINYEE_connect_btn.setText(self.app_lang["DP832_connect_dev_btn_text_no"])

    def JINYEE_info(self, data):
        pass

    def JINYEE_warn(self, data):
        pass

    def JINYEE_error(self, data):
        pass


class SPMK_FUNCTIONS:

    def SPMK_INIT(self):
        id1, id2 = self.COM_select_Combox.currentText().split(" - ")[0:2]
        if self.Tread_SPMK is None:
            self.Tread_SPMK = SPMK51XT(str(id1), str(id2))
            self.Tread_SPMK.build.connect(lambda x: SPMK_FUNCTIONS.SPMK_build(self, x))
            self.Tread_SPMK.info.connect(lambda x: SPMK_FUNCTIONS.SPMK_info(self, x))
            self.Tread_SPMK.warn.connect(lambda x: SPMK_FUNCTIONS.SPMK_warn(self, x))
            self.Tread_SPMK.error.connect(lambda x: SPMK_FUNCTIONS.SPMK_error(self, x))
            self.Tread_SPMK.finished.connect(lambda: print("线程结束"))
            self.Tread_SPMK.finished.connect(lambda: self.Tread_SPMK.deleteLater())
            self.Tread_SPMK.start()
        else:
            SPMK_FUNCTIONS.SPMK_Update(self)

    def SPMK_START(self):
        if self.Tread_SPMK.is_paused:
            if self.SPMK_lineEdit.text():
                temp = self.SPMK_lineEdit.text().split(" ")
            if temp:
                self.Tread_SPMK.Update_thread([i for i in temp])
        else:
            SPMK_FUNCTIONS.SPMK_STOP(self)

    def SPMK_Update(self):
        id1, id2 = self.COM_select_Combox.currentText().split(" - ")[0:2]
        self.Tread_SPMK.port = str(id1)
        self.Tread_SPMK.Communications_status = bool(0)
        self.Tread_SPMK.is_paused = bool(1)

    def SPMK_STOP(self):
        self.Tread_SPMK.is_paused = bool(1)

    def SPMK_build(self, flag):
        if flag:
            self.SPMK_connect_btn.setIcon(self.SPMK_connect_btn_btn_icon_ok)
            self.SPMK_connect_btn.setText(self.app_lang["DP832_connect_dev_btn_text_ok"])
        else:
            self.SPMK_connect_btn.setIcon(self.SPMK_connect_btn_btn_icon_no)
            self.SPMK_connect_btn.setText(self.app_lang["DP832_connect_dev_btn_text_no"])

    def SPMK_info(self, data):
        pass

    def SPMK_warn(self, data):
        pass

    def SPMK_error(self, data):
        pass
